package com.cmwa.solution.interceptor;

import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.cmwa.ec.base.util.SpringUtil;
import com.cmwa.solution.base.entity.Employee;
import com.cmwa.solution.sys.client.Client;
import com.cmwa.solution.sys.client.ClientManager;
import com.cmwa.solution.sys.menu.service.MenuService;
import com.cmwa.solution.sys.permission.authority.dao.AuthorityDao;
import com.cmwa.solution.utils.SessionUtils;
import com.cmwa.solution.utils.cached.MenuCached;
import com.cmwa.solution.utils.spring.SpringContextUtil;

/**
 * 注： 如果 员工-权限 表，没有员工A的数据，则A的权限是其岗位的权限（即 岗位-权限 表的数据）； 如果 员工-权限 表 有A的数据，则A的权限 为
 * 员工-权限 表 中的数据 即员工-权限优先原则
 * 
 * @author pangtf
 * 
 */
public class AuthInterceptor implements HandlerInterceptor {
	
	private List<String> excludeUrls;
	private String welcomeUrl;
	@Resource
	private MenuCached menuCached;
	@Resource
	private AuthorityDao authorityDao;

	public List<String> getExcludeUrls() {
		return excludeUrls;
	}
	public void setExcludeUrls(List<String> excludeUrls) {
		this.excludeUrls = excludeUrls;
	}
	public void setWelcomeUrl(String welcomeUrl) {
		this.welcomeUrl = welcomeUrl;
	}
	public String getWelcomeUrl() {
		return welcomeUrl;
	}
	/**
	 * 在调用controller方法前拦截
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		Employee employee = SessionUtils.getEmployee();
		SpringContextUtil.getBean(MenuService.class).buildMenuMap(employee);
		

//		String path = request.getServletPath();
		
		/**
		 * PermissionAuth.resourceType()：用于判断操作的是那一层的资源数据
		 * 		PROJECT: 系列产品层级
		 * 		注：因为当前CBP默认的层级值有上述三种，因此，像子产品层级的，需传产品ID过来
		 * PermissionAuth.operateCodes()：用于判断当前登录人是否有使用权限,注解中传过来的是按钮对应的权限id
		 * 资源ID：用于判断当前登录人是否有操作该资源的权限(需在前端传过来)
		 * 
		 * 1、首先判断是否有登录人，若没有，则不允许访问
		 * 2、根据人+资源+操作判断是否有操作的权限
		 * @author ex-sujh
		 * @date 2018年7月5日14:58:24
		 */
		// 当前登录人
		String currentEmpId = employee.getID();
		String loginUrl = SpringUtil.getProperty("sys.nonPrivilegedUrl");
		// 如果没有登录人，则不允许访问
		if (StringUtils.isBlank(currentEmpId)) {
			// 重定向登录页面URL
			/*String redireUrl = SpringUtil.getProperty("sys.loginUrl");
			response.sendRedirect(loginUrl + "?type=noLogin&redireUrl=" + redireUrl);
			return false;*/
		}
		String requestPath = request.getRequestURI();// 用户访问的资源地址
		if (excludeUrls.contains(requestPath)) {
			// 如果该请求不在拦截范围内，直接返回true
			return true;
		} else {
			int status = checkMenuAuth(request);
			if (status == -1) {
				//状态为-1，说明用户没有权限
				response.sendRedirect(loginUrl + "?type=nonPrivileged");
				return false;
			} else if (status == -2) {
				//状态为-2，说明用户没有登录
				// 重定向登录页面URL
				String redireUrl = SpringUtil.getProperty("sys.loginUrl");
				response.sendRedirect(loginUrl + "?type=noLogin&redireUrl=" + redireUrl);
				return false;
			} else if (status == 0) {
				//状态为0，说明用户已经登录过了，但是缓存中的权限已经被清空了
				response.sendRedirect(loginUrl + "?type=nonPrivileged");
				return false;
			}
			return true;
		}
	}
	
	/**
	 * 判断是否有菜单权限
	 * 
	 * @param request
	 * @return
	 */
	private int checkMenuAuth(HttpServletRequest request) {
		int status = 1;
		// 是否是菜单表中管理的url
		String visitMenuId = menuCached.findMatchUrlMenu(request);

		// 不在管理中的URL默认是有权限访问
		if (visitMenuId == null) {
			return status;
		}
		// 从缓存中获取用户拥有的权限菜单
		Client client = ClientManager.getInstance().getClient();
		if (client != null && client.getMenus() != null) {
			if (client.getMenus().size() != 0) {
				status = client.getMenus().containsKey(visitMenuId) ? 1 : -1;
			} else {
				//状态为0，说明用户已经登录过了，但是缓存中的权限已经被清空了
				status = 0;
			}
		} else {
			status = -2;
		}
		return status;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
	}

}
